const fs = require('fs')
const path = require('path')
const mongoose = require('mongoose')
const initShopData = require('../../shopData')
const { Shop } = require('../../schema')
const { host } = require('../../../../config')
const { ObjectId } = mongoose.Types

mongoose.connect('mongodb://127.0.0.1:27017/sportswear').then()
const shopCollection = mongoose.model('shop', Shop)

function initData () {
    let data = initShopData
    data = data.map(item => {
        item.proid = ObjectId(item.proid)
        item.swiper = item.swiper.map(items => items.replace(/.*(?=\/static)/, host))
        return item
    })
    return new Promise((resolve, reject) => {
        shopCollection.insertMany(data).then(res => {
            resolve(res)
        }).catch(err => {
            reject(err)
        })
    })
}

function getProductDetail (proid) {
    return new Promise(resolve => {
        shopCollection.findOne({
            proid
        }).then(res => {
            resolve(res)
        })
    })
}

function insertProduct ({ brand, category, proname, originprice, discount, stock, desc, swiper }) {
    const record = new shopCollection({
        proid: ObjectId(),
        sales: 0,
        time: new Date(new Date().getTime() + 8 * 60 * 60 * 1000),
        issale: true,
        isrecommend: false,
        isseckill: false, ...{ brand, category, proname, originprice, discount, stock, desc, swiper }
    })
    return new Promise((resolve, reject) => {
        record.save().then(res => {
            resolve(res)
        }).catch(err => {
            reject(err)
        })
    })
}

function removeProductList (proid) {
    return new Promise((resolve, reject) => {
        shopCollection.findOne({
            proid
        }).then(res => {
            res.swiper.forEach(item => {
                try {
                    let absolutePath = path.join(__dirname, '../../../../', item.replace(host + '/static', 'server'))
                    fs.rmSync(absolutePath)
                } catch (err) {
                    if (err.toString().includes('is not a function')) {
                        resolve('数据删除成功，但是服务器硬盘图片资源无法删除！兼容性问题，请提升node版本至16.13.2')
                    } else {
                        resolve('数据删除成功,网络图片资源无法在服务器硬盘删除（正常）')
                    }
                }
            })
            shopCollection.deleteOne({
                proid
            }).then(res => {
                if (res.deletedCount) {
                    resolve('删除商品成功')
                } else {
                    resolve('未找到商品,或该商品已经被删除')
                }
            }).catch(err => {
                reject(err)
            })
        }).catch(err => {
            reject('商品不存在')
        })
    })
}

function modifyProductList (proid, data) {
    let _data = {
        brand: undefined,
        category: undefined,
        proname: undefined,
        originprice: undefined,
        discount: undefined,
        stock: undefined,
        desc: undefined,
        swiper: undefined
    }

    _data = Object.assign(_data, data)

    for (let key in _data) {
        if (!_data[key]) {
            delete _data[key]
        }
    }
    if (_data.discount && _data.discount > 3) {
        _data.isseckill = false
    }

    return new Promise((resolve, reject) => {
        shopCollection.updateOne({
            proid
        }, {
            ..._data
        }).then(res => {
            if (res.modifiedCount) {
                resolve('修改商品内容成功')
            } else {
                reject('商品内容没有发生修改')
            }
        }).catch(err => {
            reject('修改的商品不存在')
        })
    })
}

function readProduct () {
    return new Promise((resolve, reject) => {
        shopCollection.find({}).sort({ time: -1 }).then(res => {
            resolve(res)
        }).catch(err => {
            reject(err)
        })
    })
}

function getProductListByState (type, flag) {
    let types = ['issale', 'isrecommend', 'isseckill']
    if (!types.includes(type)) {
        type = types[0]
    }
    return new Promise((resolve, reject) => {
        shopCollection.find({
            [type]: flag,
            issale: true
        }).sort({ operation: -1 }).then(res => {
            resolve(res)
        }).catch(err => {
            reject(err)
        })
    })
}

// 更新产品的销量和库存
function updateProductSalesAndStore (proid, derta) {
    return new Promise(resolve => {
        shopCollection.updateOne({
            proid
        }, {
            $inc: {
                sales: derta,
                stock: 0 - derta
            }
        }).then(res => {
            if (res.modifiedCount) {
                resolve('库存销量修改成功')
            } else {
                resolve('库存销量保持不变')
            }
        }).catch(err => {
            resolve('失败了')
        })
    })
}

function updateProductListState (proid, type, flag) {
    let types = ['issale', 'isrecommend', 'isseckill']
    let desc = ['上架', '推荐', '秒杀']
    if (!types.includes(type)) {
        type = types[1]
    }
    return new Promise((resolve) => {
        shopCollection.updateOne({
            proid
        }, {
            [type]: flag,
            operation: new Date(new Date().getTime() + 8 * 60 * 60 * 1000)
        }).then(res => {
            if (res.modifiedCount) {
                resolve('修改商品' + desc[types.indexOf(type)] + '状态成功')
            } else {
                resolve('商品状态没有发生修改,或商品不存在')
            }
        }).catch(err => {
            resolve('商品不存在')
        })
    })
}

function getProductListByNumber ({ count, limit = 10 }) {
    return new Promise((resolve, reject) => {
        shopCollection.find({ issale: true }).skip((count - 1) * limit).limit(limit).sort({ time: -1 }).then(res => {
            resolve(res)
        }).catch(err => {
            resolve(err)
        })
    })
}

function getCategoryProductList (category) {
    return new Promise((resolve, reject) => {
        shopCollection.find({
            category
        }).sort({ time: -1 }).then(res => {
            resolve(res)
        }).catch(err => {
            resolve(err)
        })
    })
}

function getCategoryProductListByNumber ({ nin = [], category, limit = 10 }) {
    const filter = {
        category,
        issale: true,
        proid: {
            $nin: nin
        }
    }
    return new Promise((resolve, reject) => {
        category === '全部商品' ? delete filter.category : ''
        shopCollection.find(filter).limit(limit).sort({ time: -1 }).then(res => {
            resolve(res)
        }).catch(err => {
            reject('传入的nin数组不合法')
        })
    })
}

function getBrandProductListByNumber ({ nin = [], brand, limit = 10 }) {
    return new Promise((resolve, reject) => {
        shopCollection.find({
            brand,
            proid: {
                $nin: nin
            }
        }).limit(limit).sort({ time: -1 }).then(res => {
            resolve(res)
        }).catch(err => {
            reject('传入的nin数组不合法')
        })
    })
}

function getProductOrderBySell (sales, category) {
    const filter = { issale: true, category }
    return new Promise(resolve => {
        category === '全部商品' || category === undefined ? delete filter.category : ''
        shopCollection.find(filter).sort({
            sales
        }).then(res => {
            resolve(res)
        })
    })
}

function getProductOrderByPrice (originprice, category) {
    const filter = { issale: true, category }
    return new Promise(resolve => {
        category === '全部商品' || category === undefined ? delete filter.category : ''
        shopCollection.find(filter).then(res => {
            res.sort((a, b) => {
                a._doc.price = a.originprice * a.discount / 10
                b._doc.price = b.originprice * b.discount / 10
                if (Number(originprice) === 1) {
                    return a.originprice * a.discount / 10 - b.originprice * b.discount / 10
                } else {
                    return b.originprice * b.discount / 10 - a.originprice * a.discount / 10
                }
            })
            resolve(res)
        })
    })
}

function getProductOrderByDiscount (discount, category) {
    const filter = { issale: true, category }
    return new Promise(resolve => {
        category === '全部商品' || category === undefined ? delete filter.category : ''
        shopCollection.find(filter).sort({
            discount
        }).then(res => {
            resolve(res)
        })
    })
}

function removeProductImg ({ proid, img }) {
    return new Promise((resolve, reject) => {
        // console.log(proid,img)
        shopCollection.updateOne({
            proid
        }, {
            $pull: {
                swiper: img
            }
        }).then(res => {
            if (res.modifiedCount) {
                resolve('移除商品图片' + img)
            } else {
                reject('图片已经删除')
            }
        }).catch(err => {
            reject('图片根本不存在')
        })
    })
}

function filterProductList (filter) {
    return new Promise(resolve => {
        shopCollection.find({ ...filter, issale: true }).sort({ time: -1 }).then(res => {
            resolve(res)
        })
    })
}

function searchProductList (value) {
    const reg = new RegExp(value, 'i')
    return new Promise(resolve => {
        shopCollection.find({ proname: { $regex: reg } }).then(res => {
            resolve(res)
        })
    })
}

module.exports = {
    initData,
    insertProduct,
    readProduct,
    getProductDetail,
    modifyProductList,
    updateProductListState,
    updateProductSalesAndStore,
    removeProductList,
    getCategoryProductList,
    getProductListByNumber,
    getCategoryProductListByNumber,
    getBrandProductListByNumber,
    removeProductImg,
    getProductListByState,
    getProductOrderBySell,
    getProductOrderByPrice,
    getProductOrderByDiscount,
    filterProductList,
    searchProductList
}
